#include "My_obj.h"
// //信号量
// class m_sems
// {

// public:
//     m_sems();
//     m_sems(int s_nums);
//     ~m_sems();
//     int get_semid();
//     void p_sem(int semid, int semnum);
//     void v_sem(int semid, int semnum);
//     void sem_init(int semid, int semnum, int semval);
// private:
//     int semid;
// };

// //共享内存
// class m_shm
// {
// public:
//     m_shm(int size);
//     ~m_shm();
//     int get_shmid();
//     char *get_shmaddr();
//     void  shm_copy(char*buffer);
// private:
//     int shmid;
//     char *shmaddr;
// };
// //消息队列
// class m_msg
// {
// public:
//     m_msg();
//     int m_msgsed( char *msgbuf, int msgflg=0);
//     int m_msgget(char*msgbuf,int msgtype,int msgflg=0);
//     ~m_msg();
// private:
//     int msgid;
// };
// //管道
// class m_fifo
// {
// public:
//     m_fifo( char *path, mode_t mode);
//     ~m_fifo();
//     int m_open(char *pathname,int flags);
//     int m_close(int fd);
//     int m_read(int fd,char *buf,int size);
//     int m_write(int fd,char *buf,int size);
//     int m_unlink(char *pathname);
// private:
//     int fd;
//     char *pathname;
//     mode_t mode;
// };

m_sems::m_sems()
{
    semid = -1;
}

m_sems::m_sems(int s_nums)
{
    key_t key = ftok(".", 1);
    semid = semget(key, s_nums, IPC_CREAT | 0666 | IPC_EXCL);
    if (semid == -1)
    {
        if (errno == EEXIST)
        {
            semid = semget(key, s_nums, 0666);
        }
        else
        {
            perror("semget error");
            exit(1);
        }
    }
}

m_sems::~m_sems()
{
    semctl(semid, 0, IPC_RMID);
}

int m_sems::get_semid()
{
    return semid;
}

void m_sems::p_sem(int semid, int semnum)
{
    struct sembuf sembuffer;
    sembuffer.sem_num = semnum;
    sembuffer.sem_op = -1;
    sembuffer.sem_flg = SEM_UNDO;
    if (semop(semid, &sembuffer, 1) < 0)
    {
        perror("sem op p error!\n");
        exit(1);
    }
}

void m_sems::v_sem(int semid, int semnum)
{
    struct sembuf sembuffer;
    sembuffer.sem_num = semnum;
    sembuffer.sem_op = 1;
    sembuffer.sem_flg = SEM_UNDO;
    if (semop(semid, &sembuffer, 1) < 0)
    {
        perror("sem op p error!\n");
        exit(1);
    }
}

void m_sems::init_sem(int semid, int semnum, int value)
{
    union semun
    {
        int val;
        struct semid_ds *buf;
        unsigned short *array;
    };
    union semun sem_union;
    sem_union.val = value;
    if (semctl(semid, semnum, SETVAL, sem_union) == -1)
    {
        perror("semctl error");
        exit(1);
    }
}

m_shm::m_shm(int size)
{
    key_t key = ftok(".", 1);
    shmid = shmget(key, size, IPC_CREAT | 0666 | IPC_EXCL);
    if (shmid == -1)
    {
        if (errno == EEXIST)
        {
            shmid = shmget(key, size, 0666);
        }
        else
        {
            perror("shmget error");
            exit(1);
        }
    }
    shmaddr = (char *)shmat(shmid, NULL, 0);
}

m_shm::~m_shm()
{
    shmdt(shmaddr);
    shmctl(shmid, IPC_RMID, NULL);
}

int m_shm::get_shmid()
{
    return shmid;
}

char *m_shm::get_shmaddr()
{
    return shmaddr;
}

void m_shm::shm_copy(char *buffer)
{
    memcpy(buffer, shmaddr, strlen(shmaddr));
}

m_msg::m_msg()
{
    key_t key = ftok(".", 2);
    msgid = msgget(key, IPC_CREAT | 0666 | IPC_EXCL);
    if (msgid == -1)
    {
        if (errno == EEXIST)
        {
            msgid = msgget(key, 0666);
        }
        else
        {
            perror("msgget error");
            exit(1);
        }
    }
}

int m_msg::m_msgsed(char *msgbuf, int msgflg)
{
    int i = msgsnd(msgid, msgbuf, sizeof(msgbuf) - sizeof(long), msgflg);
    if (i == -1)
    {
        perror("msgsnd error");
        exit(1);
    }
    return i;
}

int m_msg::m_msgget(char *msgbuf, int msgtype, int msgflg)
{

    int i = msgrcv(msgid, msgbuf, sizeof(msgbuf) - sizeof(long), msgtype, msgflg);
    if (i == -1)
    {
        perror("msgrcv error");
        exit(1);
    }
    return i;
}

m_msg::~m_msg()
{
    msgctl(msgid, IPC_RMID, NULL);
}

m_fifo::m_fifo(char *path, mode_t mode)
{
    mkfifo(path, mode);
    pathname = path;
}

m_fifo::~m_fifo()
{
    unlink(pathname);
}

int m_fifo::m_open(char *pathname, int flags)
{
    int fd = open(pathname, flags);
    if (fd == -1)
    {
        perror("open error");
        exit(1);
    }
    return fd;
}

int m_fifo::m_close(int fd)
{
    int c = close(fd);
    if (c == -1)
    {
        perror("close error");
        exit(1);
    }
    return c;
}

int m_fifo::m_read(int fd, char *buf, int size)
{
    int i = read(fd, buf, size);
    if (i == -1)
    {
        perror("read error");
        exit(1);
    }
    return i;
}

int m_fifo::m_write(int fd, char *buf, int size)
{
    int i = write(fd, buf, size);
    if (i == -1)
    {
        perror("write error");
        exit(1);
    }
    return i;
}

int m_fifo::m_unlink(char *pathname)
{
    int i = unlink(pathname);
    if (i == -1)
    {
        perror("unlink error");
        exit(1);
    }
    return i;
}
